<template>
  <div class="route">
    <!-- 搜索 -->
    <div class="search">
      <el-form
        :inline="true"
        class="form"
        :model="formData"
        ref="searchForm"
        :rules="rules"
      >
        <el-form-item label="地理位置" prop="geographyId">
          <el-select
            v-model="formData.geographyId"
            size="mini"
            :clearable="true"
            style="width: 100px"
          >
            <el-option
              v-for="item in geographyList"
              :key="item.id"
              :label="item.type"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" size="mini" @click="search"
            ><i class="el-icon-search"></i>查询</el-button
          >
          <el-button size="mini" @click="reset"
            ><i class="el-icon-refresh"></i>重置</el-button
          >
        </el-form-item>
        <el-form-item>
          <el-link @click="dialogVisible = true">
            去发布<i class="el-icon-s-promotion"></i>
          </el-link>
        </el-form-item>
      </el-form>
    </div>
    <!-- 线路列表 -->
    <div class="container user-common-bg" v-loading="loading">
      <div v-if="routeList.length > 0">
        <div
          class="route-item"
          v-for="item in routeList"
          @click="routeDetail(item)"
          :key="item.id"
        >
          <div class="cover">
            <img :src="item.cover" alt="" />
          </div>
          <div class="content">
            <div class="body">
              <div class="title">
                {{ item.name }}
              </div>
              <div class="user-info">
                <div class="avatar">
                  <img :src="item.avatar || defaultAvatar" alt="" />
                </div>
                <span>{{ item.nickName }} </span>
              </div>
              <div class="introduce">
                {{ item.introduce }}
              </div>
            </div>
            <div class="footer">
              <span>
                <i class="el-icon-chat-dot-square"> </i>
                {{ item.remarkCount }}
              </span>
              <span><i class="el-icon-view"></i>{{ item.views }}</span>
              <span>
                <svg
                  width="13"
                  height="13"
                  viewBox="0 0 48 48"
                  fill="rgb(250, 40, 40)"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M15 8C8.92487 8 4 12.9249 4 19C4 30 17 40 24 42.3262C31 40 44 30 44 19C44 12.9249 39.0751 8 33 8C29.2797 8 25.9907 9.8469 24 12.6738C22.0093 9.8469 18.7203 8 15 8Z"
                    fill="none"
                    stroke="#999"
                    stroke-width="4"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                  />
                </svg>
                {{ item.praise }}
              </span>
            </div>
          </div>
          <div class="icon">
            <img :src="icon" alt="" />
          </div>
        </div>
        <!-- 分页 -->
        <el-pagination
          v-show="routeList.length > 0"
          layout="prev, pager, next"
          :total="total"
          :current-page="currentPage"
          :page-size="pageSize"
          @current-change="handleCurrentChange"
          :page-count="7"
          style="text-align: right; margin-top: 24px"
        >
        </el-pagination>
      </div>
      <div class="empty" v-else>
        <el-empty description="暂无数据"></el-empty>
      </div>
    </div>
    <!-- 添加 -->
    <el-dialog
      title="添加线路"
      :visible.sync="dialogVisible"
      width="56%"
      @close="handleClose"
      :close-on-click-modal="false"
    >
      <el-form
        :model="insertData"
        label-width="90px"
        :rules="insertRules"
        ref="insertForm"
      >
        <el-form-item label="线路名称" style="width: 84%" prop="name">
          <el-input
            v-model="insertData.name"
            placeholder="请输入线路名称"
            :clearable="true"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="温度(℃)" style="width: 26%" prop="temperature">
          <el-input
            v-model="insertData.temperature"
            placeholder="请输入温度"
            :clearable="true"
            autocomplete="off"
          ></el-input>
          <span class="tip">(*999表示为暂无温度)</span>
        </el-form-item>
        <el-form-item label="地理位置" style="width: 24%" prop="geographyId">
          <el-select
            v-model="insertData.geographyId"
            :clearable="true"
            style="width: 100px"
          >
            <el-option
              v-for="item in geographyList"
              :key="item.id"
              :label="item.type"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="简介" style="width: 84%" prop="introduce">
          <el-input
            v-model="insertData.introduce"
            type="textarea"
            :rows="2"
            placeholder="请输入简介"
            :clearable="true"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="图片" style="width: 84%" prop="cover">
          <div class="upload-cover">
            <div class="cover">
              <img :src="insertData.cover || defaultCover" alt="" />
              <el-upload
                action="zhanweifu"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="changeFile"
              >
                <span v-loading="uploadLoading"></span>
              </el-upload>
            </div>
            <span class="tip" style="margin-left: 150px"
              >(*推荐用横图，提升效果)</span
            >
          </div>
        </el-form-item>
        <el-form-item label="详情" style="width: 90%" prop="detail">
          <div class="editor-container">
            <Toolbar
              style="border-bottom: 1px solid #ccc"
              :editor="editor"
              :defaultConfig="toolbarConfig"
              :mode="mode"
            />
            <Editor
              style="height: 500px; overflow-y: hidden"
              v-model="html"
              :defaultConfig="editorConfig"
              :mode="mode"
              @onCreated="onCreated"
            />
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="add" :loading="insertLoading"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { uploadFile } from "@/api/common";
import defaultCover from "@/assets/defaultCover.png";
import icon from "@/assets/jh_new.png";
import defaultAvatar from "@/assets/defaultAvatar.png";
import {
  addRoute,
  addRouteViews,
  getGeographyList,
  getRouteList,
} from "@/api/user/route";
import { Notification } from "element-ui";
import userModule from "@/utils/userInfo";
export default {
  name: "RouteView",
  components: {
    Editor,
    Toolbar,
  },
  data() {
    return {
      icon,
      defaultAvatar,
      defaultCover,
      formData: {
        geographyId: "",
      },
      rules: {
        geographyId: [
          { required: true, message: "请选择地理位置", trigger: "change" },
        ],
      },
      insertData: {
        name: "",
        temperature: "",
        geographyId: 101,
        introduce: "",
        cover: "",
        detail: "",
        personType: -1, // 管理员一律为-1
      },
      insertRules: {
        name: [{ required: true, message: "请输入线路名称", trigger: "blur" }],
        temperature: [
          { required: true, message: "请输入温度", trigger: "blur" },
          { pattern: /^[-]{0,1}[0-9]+$/, message: "请输入数字" },
        ],
        geographyId: [
          { required: true, message: "请选择地理情况", trigger: "blur" },
        ],
        introduce: [{ required: true, message: "请输入介绍", trigger: "blur" }],
        cover: [{ required: true, message: "请上传图片", trigger: "blur" }],
        detail: [{ required: true, message: "请输入详情", trigger: "blur" }],
      },
      dialogVisible: false,
      loading: false,
      insertLoading: false,
      uploadLoading: false,
      geographyList: [],
      routeList: [],
      page: 1,
      pageSize: 10,
      currentPage: 1,
      total: 0,
      // 富文本框配置
      editor: null,
      html: "",
      toolbarConfig: {},
      editorConfig: {
        placeholder: "请输入内容...",
        MENU_CONF: {},
      },
      mode: "default", // or 'simple'
    };
  },
  created() {
    this.getGeographyList();
    this.getRouteList();
    // 图片配置设置
    this.configImage();
    // 视频配置设置
    this.configVideo();
  },
  beforeDestroy() {
    const editor = this.editor;
    if (editor == null) return;
    editor.destroy(); // 组件销毁时，及时销毁编辑器
  },
  methods: {
    // 搜索
    search() {
      this.$refs.searchForm.validate(async (v) => {
        if (v) {
          this.page = 1;
          this.currentPage = 1;
          this.getRouteList();
        }
      });
    },
    // 重置
    reset() {
      this.page = 1;
      this.currentPage = 1;
      this.$refs.searchForm.resetFields();
      this.getRouteList();
    },
    // 获取地理位置列表
    async getGeographyList() {
      const res = await getGeographyList();
      this.geographyList = res.data;
    },
    // 获取线路列表
    async getRouteList() {
      try {
        this.loading = true;
        const res = await getRouteList({
          page: this.page,
          pageSize: this.pageSize,
          ...this.formData,
        });
        this.routeList = res.data.records;
        this.total = res.data.total;
      } catch {
        this.$message.error("获取列表失败");
      } finally {
        this.loading = false;
      }
    },
    // 查看详情
    async routeDetail(item) {
      // 新增访问量
      item.views = item.views + 1;
      const res = await addRouteViews({ id: item.id, views: item.views });
      this.$router.push(`/routeDetail/${item.id}`);
    },
    // 新增
    add() {
      this.insertData.detail = this.html;
      this.$refs.insertForm.validate(async (v) => {
        if (v) {
          try {
            this.insertLoading = true;
            this.insertData.personType = userModule.getUser().id;
            const res = await addRoute(this.insertData);
            this.dialogVisible = false;
            this.getRouteList();
            this.html = "";
          } catch {
            this.$message.error("发布失败");
          } finally {
            this.insertLoading = false;
          }
        }
      });
    },
    // 选择文件，上传封面
    async changeFile(file) {
      // 判断格式是否正确
      const bool = this.verifyFormat(file);
      if (!bool) {
        return;
      }
      // 上传到服务器
      // console.log("上传到服务器,返回图片路径赋值给insertForm.cover");
      this.uploadLoading = true;
      try {
        let formData = new FormData();
        // 拿到存在file中的文件存放到formData中
        formData.append("file", file.raw);
        const res = await uploadFile(formData);
        this.insertData.cover = res.data;
        this.updateData.cover = res.data;
      } finally {
        this.uploadLoading = false;
      }
    },
    // 上传封面前校验格式
    verifyFormat(file) {
      const isJPG =
        file.raw.type === "image/jpeg" || file.raw.type === "image/png";
      const isLt10M = file.raw.size / 1024 / 1024 < 10;
      if (!isJPG) {
        this.$message.error("上传头像图片只能是 jpg/jpeg/png 格式!");
        return false;
      }
      if (!isLt10M) {
        this.$message.error("上传头像图片大小不能超过 10MB!");
        return false;
      }
      return isJPG && isLt10M;
    },
    // 分页
    handleCurrentChange(page) {
      this.page = page;
      this.currentPage = page;
      this.getRouteList();
    },
    // 关闭弹窗
    handleClose() {
      this.insertLoading = false;
      this.html = "";
      this.$refs.insertForm.resetFields();
    },
    // 富文本框配置
    onCreated(editor) {
      this.editor = Object.seal(editor); // 一定要用 Object.seal() ，否则会报错
    },
    // 富文本框自定义图片上传
    configImage() {
      this.editorConfig.MENU_CONF["uploadImage"] = {
        // 自动定义上传图片
        async customUpload(file, insertFn) {
          // 判断格式是否正确
          const isJPG = file.type === "image/jpeg" || file.type === "image/png";
          const isLt10M = file.size / 1024 / 1024 < 10;
          if (!isJPG) {
            this.$message.error("上传图片只能是 jpg/jpeg/png 格式!");
            return false;
          }
          if (!isLt10M) {
            this.$message.error("上传图片大小不能超过 10MB!");
            return false;
          }

          const notify = Notification({
            title: "提示",
            message: "正在上传图片",
            showClose: false,
            iconClass: "el-icon-loading",
            duration: 0,
          });
          try {
            // 上传到服务器
            let formData = new FormData();
            // 拿到存在file中的文件存放到formData中s
            formData.append("file", file);
            const res = await uploadFile(formData);
            insertFn(res.data);
            notify.close();
            Notification.success({
              title: "上传成功",
              duration: 2000,
            });
          } catch {
            notify.close();
            Notification.error({
              title: "错误",
              message: "上传失败",
              duration: 2000,
            });
          }
        },
      };
    },
    // 富文本框自定义视频上传
    configVideo() {
      this.editorConfig.MENU_CONF["uploadVideo"] = {
        // 自动定义上传视频
        async customUpload(file, insertFn) {
          // 判断格式是否正确
          const isJPG = file.type === "video/mp4";
          const isLt20M = file.size / 1024 / 1024 < 20;
          if (!isJPG) {
            this.$message.error("上传视频只能是 mp4 格式!");
            return false;
          }
          if (!isLt20M) {
            this.$message.error("上传视频大小不能超过 20MB!");
            return false;
          }

          const notify = Notification({
            title: "提示",
            message: "正在上传视频",
            showClose: false,
            iconClass: "el-icon-loading",
            duration: 0,
          });
          try {
            // 上传到服务器
            let formData = new FormData();
            // 拿到存在file中的文件存放到formData中s
            formData.append("file", file);
            const res = await uploadFile(formData);
            insertFn(res.data);
            notify.close();
            Notification.success({
              title: "上传成功",
              duration: 2000,
            });
          } catch {
            notify.close();
            Notification.error({
              title: "错误",
              message: "上传失败",
              duration: 2000,
            });
          }
        },
      };
    },
  },
};
</script>

<style lang="less" scoped>
.route {
  text-align: left;
  .search {
    margin: 0 auto;
    width: 90%;
    height: 70px;
    .form {
      padding-top: 18px;
      height: 100%;
    }
  }
  .container {
    height: 100%;
    padding-bottom: 10px;
    .route-item {
      display: flex;
      margin-bottom: 10px;
      padding: 20px;
      height: 210px;
      border-radius: 8px;
      box-shadow: 0 0 8px #ccc;
      cursor: pointer;
      &:hover {
        .content {
          .title {
            color: rgb(255, 160, 0);
          }
        }
      }
      .cover {
        width: 280px;
        height: 100%;
        border-radius: 8px;
        img {
          width: 100%;
          height: 100%;
          border-radius: inherit;
        }
      }
      .content {
        flex: 1;
        margin: 0 16px;
        .body {
          height: 90%;
          .title {
            font-size: 19px;
            font-weight: 600;
            transition: all 0.2s;
          }
          .user-info {
            display: flex;
            align-items: center;
            margin: 6px 0;
            .avatar {
              width: 24px;
              height: 24px;
              border-radius: 50%;
              margin-right: 8px;
              img {
                width: 100%;
                height: 100%;
                border-radius: inherit;
              }
            }
          }
          .introduce {
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 4;
            -webkit-box-orient: vertical;
            color: #999;
          }
        }
        .footer {
          height: 10%;
          font-size: 15px;
          color: #999;
          span {
            margin-right: 20px;
            i {
              margin-right: 4px;
            }
          }
        }
      }
      .icon {
        width: 80px;
        height: 80px;
        img {
          width: 100%;
          height: 100%;
        }
      }
    }
    .empty {
      height: 100%;
      box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);
      border-radius: 8px;
    }
  }
  .tip {
    position: absolute;
    margin-left: 10px;
    width: 100%;
    font-size: 12px;
    color: #aaa;
  }
  .upload-cover {
    position: relative;
    display: flex;
    width: 140px;
    height: 140px;
    .cover {
      width: 100%;
      height: 100%;
      position: relative;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      img {
        width: 100%;
        height: 100%;
        cursor: pointer;
      }
      span {
        position: absolute;
        top: 50%;
        left: 50%;
        width: 134px;
        height: 134px;
        transform: translate(-50%, -50%);
        &::before {
          content: "上传封面";
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          width: 134px;
          height: 134px;
          background-color: rgba(0, 0, 0, 0.06);
          text-align: center;
          line-height: 134px;
          cursor: pointer;
          opacity: 0;
          visibility: hidden;
          z-index: 1;
          color: black;
        }
        &:hover::before {
          opacity: 1;
          visibility: visible;
        }
      }
    }
  }
  .editor-container {
    text-align: left;
    border: 1px solid;
  }
}
</style>